<template>
  <div ref="domRef" class="dom-wrapper"></div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import * as THREE from 'three';
/**
 * 材质不同的区别介绍
 * 1. 材质的分类
 * 2. 材质的使用场景
 * 3. 材质的使用方法
 * 4. 材质的使用注意事项
 * 5. 材质的使用技巧
 */
const domRef = ref(null);
let scene: THREE.Scene;
let controls: OrbitControls;
let camera: THREE.PerspectiveCamera;
let renderer: THREE.WebGLRenderer;

const init = (warpDom: HTMLElement) => {
  // scene
  scene = new THREE.Scene();

  // camera
  const SCREEN_WIDTH = warpDom.clientWidth;
  const SCREEN_HEIGHT = warpDom.clientHeight;
  const VIEW_ANGLE = 45,
    ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT,
    NEAR = 0.1,
    FAR = 20000;
  camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
  camera.position.set(0, 150, 400);
  camera.lookAt(scene.position);
  scene.add(camera);

  // light
  const light = new THREE.PointLight(0xffffff);
  light.position.set(0, 150, 100);
  scene.add(light);

  // renderer
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
  controls = new OrbitControls(camera, renderer.domElement);
  warpDom.appendChild(renderer.domElement);

  // floor
  const floorTexture = new THREE.TextureLoader().load('images/checkerboard.jpg');
  floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
  floorTexture.repeat.set(10, 10);
  const floorMaterial = new THREE.MeshBasicMaterial({ map: floorTexture, side: THREE.DoubleSide });
  const floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
  const floor = new THREE.Mesh(floorGeometry, floorMaterial);
  floor.position.y = -0.5;
  floor.rotation.x = Math.PI / 2;
  scene.add(floor);

  // create a small sphere to show position of light
  const lightbulb = new THREE.Mesh(
    new THREE.SphereGeometry(10, 16, 8),
    new THREE.MeshBasicMaterial({ color: 0xffaa00 })
  );
  lightbulb.position.copy(light.position);
  scene.add(lightbulb);

  ////////////
  // CUSTOM //
  ////////////
  // Sphere parameters: radius, segments along width, segments along height
  const sphereGeom = new THREE.SphereGeometry(50, 32, 16);

  // Three types of materials, each reacts differently to light.
  const darkMaterial = new THREE.MeshBasicMaterial({ color: 0x000088 });
  const darkMaterialL = new THREE.MeshLambertMaterial({ color: 0x000088 });
  const darkMaterialP = new THREE.MeshPhongMaterial({ color: 0x000088 });

  // Creating three spheres to illustrate the different materials.
  // Note the clone() method used to create additional instances
  //    of the geometry from above.
  let sphere = new THREE.Mesh(sphereGeom.clone(), darkMaterial);
  sphere.position.set(-150, 50, 0);
  scene.add(sphere);

  sphere = new THREE.Mesh(sphereGeom.clone(), darkMaterialL);
  sphere.position.set(0, 50, 0);
  scene.add(sphere);

  sphere = new THREE.Mesh(sphereGeom.clone(), darkMaterialP);
  sphere.position.set(150, 50, 0);
  scene.add(sphere);
};
const render = () => {
  renderer.render(scene, camera);
};
const animate = () => {
  requestAnimationFrame(animate);
  render();
};
onMounted(() => {
  if (domRef.value) {
    init(domRef.value);
    animate();
  }
});
</script>

<style scoped>
.dom-wrapper {
  width: 100%;
  height: 100%;
}
</style>
